﻿/********
* 
* 
*  Description:
*  Create By Kain at 4/6/2011 4:48:52 PM
*  
*
*  Revision History:
*  Date                  Who                 What
*  
* 
*/

#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

#endregion

namespace Cherry.Agile.ServiceModel.Runtime
{
    internal class ServiceRunner:IServiceRunner
    {
        IServiceRunner _inner;
        AppDomain _domain;
       

        public ServiceRunner() { }

        public ServiceRunner(ServicePackage package)
        {
            ServicePackage = package;
            Load();
        }

        public ServicePackage ServicePackage { get; private set; }

        public void Load()
        {
            Load(ServicePackage);
        }

        public void Load(ServicePackage package)
        {
            Unload();
            ServicePackage = package;
            var domain = _domain = DomainManager.CreateDomain(package);
            var agent = DomainAgent.CreateInstance(domain);
            _inner = agent.CreateRunner();
            _inner.Load(package);
            _unloaded = false;
        }

        public void Run(IEventListener listener, IServiceFilter filter)
        {
            if (_domain == null)
                Load();
            var thread = new Thread(new ThreadStart(() => { _inner.Run(listener, filter); }));
            thread.Start();
        }

        public void Stop(IEventListener listener, IServiceFilter filter)
        {
            var thread = new Thread(new ThreadStart(() => { _inner.Stop(listener, filter);}));
            thread.Start();
        }

        public IEnumerable<ServiceInfo> Info(IServiceFilter filter)
        {
            if(_domain == null)
                return new ServiceInfo[]{new ServiceInfo(){ State = RunState.NotRunnable}};
            return _inner.Info(filter);
        }

        public void Unload()
        {
            if (_domain != null)
                AppDomain.Unload(_domain);
            _domain = null;
            _unloaded = true;
        }

        bool _unloaded;
        public bool Unloaded { get { return _unloaded; } }
        
        public IEnumerable<ServiceInfo> GetServicesInfo() {
            return _inner.GetServicesInfo();
        }
    }
}
